#include <iostream>
#include <cstring>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>

using namespace std;

void handler(int signo)
{
    sleep(5);

    while (true) 
    {
        //pid_t rid = waitpid(-1,nullptr,0);
        pid_t rid = waitpid(-1,nullptr,WNOHANG);

        if (rid > 0)
        {
            cout << "子进程退出, 回收成功, child id: " << rid << endl;
        }
        else if (rid == 0)
        {
            cout << "退出的子进程已经全部回收" << endl;
            break;
        }
        else
        {
            cout << "wait error" << endl;
            break;
        }
    }
    cout << "I am process: " << getpid() << "catch a signo: " << signo << endl;
}


int main()
{
    //signal(17,handler);
    signal(SIGCHLD,SIG_IGN); //SIG_DFL -> action -> IGN

   for (int i = 0; i < 10; i++)
   {
        pid_t id = fork();

        if (id == 0)
        {
            //child
            while (true)
            {
                cout << "I am child process: " << getpid() << ",pid" << getppid() << endl;
                sleep(1);
                break;
            }

            exit(0);
        }
   }

    //father
    while (true)
    {
        cout << "I am a father process: " << getpid() << endl;
        sleep(1);
    }

    return 0;
    
}





















//问题一: pending位图,什么时候从1->0. 执行信号捕捉方法之前, 先清0, 在调用
//问题二: 信号被处理的时候, 对应的喜欢也会被添加到block表中, 防止信号被嵌套调用

void PrintPending()
{
    sigset_t set;
    sigpending(&set);

    for (int signo = 1; signo <= 31; signo++)
    {
        if (sigismember(&set,signo)) cout << "1";
        else cout << "0";
    }
    cout << endl;
}

// void handler (int signo)
// {
//     cout << "catch a signal, signal number : " << signo << endl;

//     while (true)
//     {
//         PrintPending();

//         sleep(1);
//     }
// }

// int main()
// {
//     struct sigaction act,oact;
//     memset(&act,0,sizeof(act));
//     memset(&oact,0,sizeof(oact));

//     sigemptyset(&act.sa_mask);
//     sigaddset(&act.sa_mask,1);
//     sigaddset(&act.sa_mask,2);
//     sigaddset(&act.sa_mask,3);

//     act.sa_handler = handler;

//     sigaction(2,&act,&oact);

//     while (true)
//     {
//         cout << "I am a process: " << getpid() << endl;
//         sleep(1);
//     }
// }